package main

import (
	"fmt"
	"github.com/satori/go.uuid"
	"net"
	"strings"
)

type User struct {
	Name string
	Addr string
	C    chan string
	Conn net.Conn

	// 关联server
	Server *Server
}

// NewUser 创建用户
func NewUser(conn net.Conn, server *Server) *User {
	username := uuid.NewV1().String()
	addr := conn.RemoteAddr().String()

	return &User{
		Name:   username,
		Addr:   addr,
		C:      make(chan string),
		Conn:   conn,
		Server: server,
	}
}

// 启动ListenMessage监听消息的goroutine
func (u *User) start() {
	go u.ListenMessage()
}

// ListenMessage 监听当前用户的channel，若有消息则发送给对端客户端
func (u *User) ListenMessage() {
	for {
		msg, err := <-u.C
		if !err {
			fmt.Printf("用户【%s】发送失败：%v", u.Name, err)
			continue
		}
		u.Conn.Write([]byte(msg + "\n"))
	}
}

// 用户上线业务
func (u *User) Online() {
	// 将用户加入到OnlineMap中
	u.Server.mapLock.Lock()
	u.Server.OnlineMap[u.Name] = u
	u.Server.mapLock.Unlock()

	// 广播当前用户的上线消息
	u.Server.BroadCast(u, "已上线")
}

// 用户下线业务
func (u *User) Offline() {
	// 将用户从OnlineMap删除
	u.Server.mapLock.Lock()
	delete(u.Server.OnlineMap, u.Name)
	u.Server.mapLock.Unlock()

	// 广播当前用户的下线消息
	u.Server.BroadCast(u, "已下线")
}

// 给当前用户发消息
func (u User) sendMsg(msg string) {
	u.Conn.Write([]byte(msg))
}

// 用户处理消息
func (u *User) DoMessage(msg string) {
	// 特定指令
	if msg == "getUsers" {
		// 查询当前所有在线用户
		u.Server.mapLock.Lock()
		for _, user := range u.Server.OnlineMap {
			onlineMsg := "【" + user.Name + "】：" + user.Addr + " 在线\n"
			u.sendMsg(onlineMsg) // 发给当前用户
			// 或者直接 u.C <- onlineMsg
		}
		u.Server.mapLock.Unlock()
		return
	} else if len(msg) > 7 && msg[:7] == "rename|" {
		// 修改用户名
		// newName := strings.Split(msg, "|")[1]
		newName := msg[7:]
		// 判断name是否重复
		if _, ok := u.Server.OnlineMap[newName]; ok {
			u.sendMsg("当前用户名已被占用\n")
		} else {
			// 删除旧的，新增新的
			u.Server.mapLock.Lock()
			u.Server.OnlineMap[newName] = u.Server.OnlineMap[u.Name]
			u.Name = newName
			delete(u.Server.OnlineMap, u.Name)
			u.Server.mapLock.Unlock()

			u.sendMsg("更新成功\n")
		}
		return
	} else if len(msg) > 4 && msg[:3] == "to|" {
		// 私聊：to|张三|你好
		// 1.获取对方的用户名
		dstName := strings.Split(msg, "|")[1]
		if dstName == "" {
			u.sendMsg("私聊格式错误，请使用如“to|张三|你好”的格式\n")
			return
		}
		// 2.根据用户名得到user对象
		dstUser, ok := u.Server.OnlineMap[dstName]
		if !ok {
			u.sendMsg("找不到用户：" + dstName + "\n")
			return
		}
		// 3.将消息内容，通过user对象发送给指定用户
		content := strings.Split(msg, "|")[2]
		if content == "" {
			u.sendMsg("请输入消息内容\n")
			return
		}
		dstUser.sendMsg("【" + u.Name + "】对你说：" + content + "\n")
	}

	u.Server.BroadCast(u, msg)
}
